package main;

import gerencia.FachadaAlocacao;

import java.util.Scanner;

import util.ManipulaDatas;

import descricoes.Evento;
import descricoes.EventoAlocado;
import descricoes.Sala;

public class MainMenu {

	private final int ADICIONAR_SALA = 1;
	private final int ADICIONAR_EVENTO = 2;
	private final int ALOCAR_EVENTO = 3;
	private final int LOCALIZAR_EVENTO = 4;
	private final int DESALOCAR_EVENTO = 5;
	private final int CANCELAR_EVENTO = 6;
	private final int REMOVER_SALA = 7;
	private final int SAIR = 8;

	private Scanner sc = new Scanner(System.in);
	private FachadaAlocacao grAlocacoes;

	public MainMenu() throws Exception {
		setGrAlocacoes(new FachadaAlocacao());
	}

	public void menuPrincipal() throws Exception {
		int opcao = 0;
		System.out.println("##########################################");
		System.out.println("####                                  ####");
		System.out.println("####      MENU ALOCACAO DE SALAS      ####");
		System.out.println("####                                  ####");
		System.out.println("####       1 - Adicionar sala         ####");
		System.out.println("####       2 - Adicionar evento       ####");
		System.out.println("####       3 - Alocar evento          ####");
		System.out.println("####       4 - Localizar evento       ####");
		System.out.println("####       5 - Desalocar evento       ####");
		System.out.println("####       6 - Cancelar evento        ####");
		System.out.println("####       7 - Remover sala           ####");
		System.out.println("####       8 - Sair                   ####");
		System.out.println("####                                  ####");
		System.out.println("##########################################");

		System.out.println("\nDigite o numero escolhido: ");

		while (true) {
			opcao = sc.nextInt();

			if (0 < opcao && opcao < 9)
				break;
			System.out.println("Digite um numero valido:");
		}

		switch (opcao) {
		case ADICIONAR_SALA:
			menuAddSala();

		case ADICIONAR_EVENTO:
			menuAddEvento();

		case ALOCAR_EVENTO:
			menuAlocarEvento();

		case LOCALIZAR_EVENTO:
			menuLocalizarEvento();

		case DESALOCAR_EVENTO:
			menuDesalocarEvento();

		case CANCELAR_EVENTO:
			menuCancelarEvento();

		case REMOVER_SALA:
			menuRemoverSala();

		case SAIR:
			menuSair();
		}
	}

	public void menuAddSala() throws Exception {
		System.out
				.println("______________________________________________________");
		System.out.println("\n# Adicionar Sala #");

		String finalidade = escolherFinalidade();

		System.out.println("\nDigite o ID da sala:");
		String ID = "";
		String escolha = "S";
		while (true) {
			ID = sc.next();
			if (getGrAlocacoes().localizaSala(ID) == null)
				break;
			System.out
					.println("Ja existe sala com esse ID. Digitar novamente? S/N");
			escolha = sc.next();
			if (escolha.toUpperCase().equals("S")) {
				System.out.println("\nDigite a ID do evento: ");
			} else {
				break;
			}
		}

		if (escolha.toUpperCase().equals("S")) {
			System.out.println("\nDigite a capacidade da sala:");
			int capacidade = sc.nextInt();

			String tipo = escolherTipo(finalidade);

			System.out.println("\nDigite o apelido da sala:");
			String apelido = sc.next();

			boolean aberto = estaAberto(finalidade);

			getGrAlocacoes().addSala(finalidade, ID, capacidade, tipo, apelido,
					aberto);

			System.out.println("\nA sala " + ID
					+ " foi adicionada com sucesso!");

		}

		System.out
				.println("______________________________________________________");
		System.out.println("\nEscolha o que deseja fazer agora:");
		System.out.println("1 - Adicionar uma nova sala");
		System.out.println("2 - Voltar ao menu principal");
		System.out.println("\nDigite o numero escolhido: ");

		while (true) {
			int opcao = sc.nextInt();
			if (opcao == 1) {
				menuAddSala();
				break;
			} else if (opcao == 2) {
				menuPrincipal();
				break;
			}
			System.out.println("\nNumero invalido. Digite novamente:");
		}

	}

	private String escolherFinalidade() {
		String finalidade = "";
		System.out
				.println("\nEscolha a finalidade da sala de acordo com as opcoes: ");
		System.out
				.println("\n1 - Escritorio \n2 - Laboratorio \n3 - Sala de aula \n4 - Sala de conferencia");
		System.out.println("\nDigite a opcao escolhida: ");

		while (true) {
			int opcaoEscolhida = sc.nextInt();
			if (opcaoEscolhida == 1) {
				finalidade = "Escritorio";
				break;
			} else if (opcaoEscolhida == 2) {
				finalidade = "Laboratorio";
				break;
			} else if (opcaoEscolhida == 3) {
				finalidade = "Sala de aula";
				break;
			} else if (opcaoEscolhida == 4) {
				finalidade = "Sala de conferencia";
				break;
			}
			System.out.println("\nDigite um numero valido:");
		}

		return finalidade;
	}

	public String escolherTipo(String finalidade) {
		String tipo = "";
		if (!finalidade.equals("Escritorio")) {
			System.out
					.println("\nEscolha o tipo da sala de acordo com as opcoes: ");

			if (finalidade.equals("Sala de aula")) {
				System.out
						.println("\n1 - Normal \n2 - Inteligente \n3 - Videoconferencia");
			} else if (finalidade.equals("Sala de conferencia")) {
				System.out.println("\n1 - Normal \n2 - Videoconferencia");
			} else if (finalidade.equals("Laboratorio")) {
				System.out
						.println("\n1 - Quimica \n2 - Fisica \n3 - Biologia \n4 - Computacao");
			} else if (finalidade.equals("Sala de conferencia")) {
				System.out.println("\n1 - Normal \n2 - Videoconferencia");
			}

			System.out.println("\nDigite o tipo escolhido:");
			while (true) {
				int opcaoEscolhida = sc.nextInt();

				if (finalidade.equals("Sala de aula")) {
					if (opcaoEscolhida == 1) {
						tipo = "Normal";
						break;
					}
					if (opcaoEscolhida == 2) {
						tipo = "Inteligente";
						break;
					}
					if (opcaoEscolhida == 3) {
						tipo = "Videoconferencia";
						break;
					}
				} else if (finalidade.equals("Sala de conferencia")) {
					if (opcaoEscolhida == 1) {
						tipo = "Normal";
						break;
					}
					if (opcaoEscolhida == 2) {
						tipo = "Videoconferencia";
						break;
					}
				} else if (finalidade.equals("Laboratorio")) {
					if (opcaoEscolhida == 1) {
						tipo = "Quimica";
						break;
					}
					if (opcaoEscolhida == 3) {
						tipo = "Biologia";
						break;
					}
					if (opcaoEscolhida == 2) {
						tipo = "Fisica";
						break;
					}
					if (opcaoEscolhida == 4) {
						tipo = "Computacao";
						break;
					}
				}
				System.out.println("Numero invalido. Digite novamente: ");
			}
		}
		return tipo;
	}

	private boolean estaAberto(String finalidade) {
		boolean aberto = false;
		if (finalidade.equals("Laboratorio")) {
			System.out.println("\nEscolha se a sala esta aberta: ");
			System.out.println("\n1 - Sim \n2 - Nao");
			System.out.println("\nDigite a opcao escolhida: ");
			while (true) {
				int opcao = sc.nextInt();
				if (0 < opcao && opcao < 3) {
					if (opcao == 1)
						aberto = true;
					break;
				}
				System.out.println("Numero invalido. Digite novamente: ");
			}
		}
		return aberto;
	}

	public void menuAddEvento() throws Exception {

		System.out
				.println("______________________________________________________");
		System.out.println("\n# Adicionar Evento #");
		System.out.println("\nDigite a ID do evento: ");

		String ID = "";

		String escolha = "S";
		while (true) {
			ID = sc.next();
			Evento ev = getGrAlocacoes().localizaEventoAdicionado(ID);
			if (ev == null) {
				break;
			}
			System.out
					.println("Ja existe evento com esse ID. Digitar novamente? S/N");
			escolha = sc.next();
			if (escolha.toUpperCase().equals("S")) {
				System.out.println("\nDigite a ID do evento: ");
			} else {
				break;
			}
		}
		sc.nextLine();

		// if auxiliar para o caso do usuario ter escolhido nao
		// digitar/adicionar mais o evento.
		if (escolha.toUpperCase().equals("S")) {
			System.out.println("\nDigite o nome do evento:");
			String nome = sc.nextLine();

			ManipulaDatas datas = new ManipulaDatas();

			System.out
					.println("\nDigite a data de inicio do evento (no formato 'dd/MM/aaaa HH:mm'):");
			String inicio = sc.nextLine();
			try {
				datas.criaCalendario(inicio);
			} catch (Exception e) {
				System.out.println("\nData invalida. Digite novamente: ");
				inicio = sc.nextLine();
			}

			System.out
					.println("\nDigite a data de termino do evento (no formato 'dd/MM/aaaa HH:mm'):");
			String fim = sc.nextLine();
			try {
				datas.criaCalendario(fim);
			} catch (Exception e) {
				System.out.println("\nData invalida. Digite novamente: ");
				fim = sc.nextLine();
			}

			System.out.println("\nDigite a area do evento:");
			String area = sc.next();

			System.out.println("\nDigite um nome para contato do evento:");
			String contato = sc.next();

			System.out
					.println("\nDigite a quantidade de repeticoes do evento:");
			int repeticoes = -1;
			while (true) {
				repeticoes = sc.nextInt();
				if (repeticoes > -1)
					break;
				System.out.println("Entrada invalida. Digite novamente: ");
			}

			getGrAlocacoes().adicionaEvento(ID, nome, inicio, fim, area,
					contato, repeticoes);

			System.out.println("\nEvento " + ID + " adicionado com sucesso.");
		}

		System.out
				.println("______________________________________________________");
		System.out.println("\nEscolha o que deseja fazer agora:");
		System.out.println("1 - Adicionar um novo evento");
		System.out.println("2 - Voltar ao menu principal");
		System.out.println("\nDigite o numero escolhido: ");

		while (true) {
			int opcao = sc.nextInt();
			if (opcao == 1) {
				menuAddEvento();
				break;
			} else if (opcao == 2) {
				menuPrincipal();
				break;
			}
			System.out.println("\nNumero invalido. Digite novamente:");
		}

	}

	public void menuAlocarEvento() throws Exception {
		System.out
				.println("______________________________________________________");
		System.out.println("\n# Alocar Evento #");
		System.out.println("\nDigite a ID do evento: ");

		String IDEvento = "";
		String escolha = "S";
		while (true) {
			IDEvento = sc.next();
			Evento evento = getGrAlocacoes().localizaEventoAdicionado(IDEvento);
			if (evento != null) {
				break;
			}
			System.out
					.println("Nao existe evento com esse ID. Digitar novamente? S/N");
			escolha = sc.next();
			if (escolha.toUpperCase().equals("S")) {
				System.out.println("\nDigite a ID do evento: ");
			} else {
				break;
			}
		}
		sc.nextLine();

		// if auxiliar para o caso do usuario ter escolhido nao
		// digitar/alocar mais o evento.
		if (escolha.toUpperCase().equals("S")) {
			System.out.println("\nDigite a ID da sala: ");

			String IDSala = "";
			while (true) {
				IDSala = sc.next();
				Sala sala = getGrAlocacoes().localizaSala(IDSala);
				if (sala != null) {
					break;
				}
				System.out
						.println("Nao existe sala com esse ID. Digite novamente.");
			}
			sc.nextLine();

			EventoAlocado eventoEncontrado = getGrAlocacoes()
					.localizaEventoAlocado(IDEvento);
			if (eventoEncontrado != null) {
				System.out.println("Esse evento ja foi alocado."
						+ "Escolha um novo Evento.");
				menuAlocarEvento();
			}

			getGrAlocacoes().alocaEvento(IDEvento, IDSala);

			System.out.println("\nEvento " + IDEvento
					+ " alocado com sucesso na sala " + IDSala);
		}
		System.out
				.println("______________________________________________________");
		System.out.println("\nEscolha o que deseja fazer agora:");
		System.out.println("1 - Alocar um novo evento");
		System.out.println("2 - Voltar ao menu principal");
		System.out.println("\nDigite o numero escolhido: ");

		while (true) {
			int opcao = sc.nextInt();
			if (opcao == 1) {
				menuAlocarEvento();
				break;
			} else if (opcao == 2) {
				menuPrincipal();
				break;
			}
			System.out.println("\nNumero invalido. Digite novamente:");
		}

	}

	public void menuLocalizarEvento() throws Exception {
		System.out
				.println("______________________________________________________");
		System.out.println("\n# Localizar Evento #");
		System.out.println("1 - Localizar evento pela ID ");
		System.out.println("2 - Localizar evento por nome ");
		System.out.println("3 - Localizar evento pelo horario ");
		System.out.println("4 - Localizar evento pelo contato ");
		System.out.println("\nDigite o numero escolhido: ");

		while (true) {
			int opcao = sc.nextInt();
			if (opcao == 1) {
				menuLocalizarEventoID();
				break;
			} else if (opcao == 2) {
				menuLocalizarEventoNome();
				break;
			} else if (opcao == 3) {
				menuLocalizarEventoHorario();
				break;
			} else if (opcao == 4) {
				menuLocalizarEventoContato();
				break;
			}
			System.out.println("\nNumero invalido. Digite novamente:");
		}

		System.out
				.println("______________________________________________________");
		System.out.println("\nEscolha o que deseja fazer agora:");
		System.out.println("1 - Localizar um novo evento");
		System.out.println("2 - Voltar ao menu principal");
		System.out.println("\nDigite o numero escolhido: ");

		while (true) {
			int opcao = sc.nextInt();
			if (opcao == 1) {
				menuLocalizarEvento();
				break;
			} else if (opcao == 2) {
				menuPrincipal();
				break;
			}
			System.out.println("\nNumero invalido. Digite novamente:");
		}

	}

	private void menuLocalizarEventoContato() {
		System.out.println("\nDigite o contato do evento: ");
		String contato = "";
		while (true) {
			contato = sc.next();
			if (!(contato == null || contato.trim().equals(""))) {
				System.out.println(getGrAlocacoes().localizaEvento("contato",
						contato));
				break;
			}
			System.out
					.println("Nao existe evento alocado com esse contato. Digitar novamente? S/N");
			String escolha = sc.next();
			if (escolha.toUpperCase().equals("S")) {
				System.out.println("\nDigite o contato do evento: ");
			} else {
				break;
			}
		}
	}

	private void menuLocalizarEventoHorario() {
		System.out
				.println("\nDigite o horario do evento (no formato 'dd/MM/aaaa HH:mm'): ");
		String horario = "";
		while (true) {
			horario = sc.next();
			if (!(horario == null || horario.trim().equals(""))) {
				System.out.println(getGrAlocacoes().localizaEvento("horario",
						horario));
				break;
			}
			System.out
					.println("Nao existe evento alocado com esse horario. Digitar novamente? S/N");
			String escolha = sc.next();
			if (escolha.toUpperCase().equals("S")) {
				System.out
						.println("\nDigite o horario do evento (no formato 'dd/MM/aaaa HH:mm'): ");
			} else {
				break;
			}
		}
	}

	private void menuLocalizarEventoNome() {
		System.out.println("\nDigite o nome do evento: ");
		String nomeEvento = "";
		while (true) {
			nomeEvento = sc.next();
			if (!(nomeEvento == null || nomeEvento.trim().equals(""))) {
				System.out.println(getGrAlocacoes().localizaEvento("nome",
						nomeEvento));
				break;
			}
			System.out
					.println("Nao existe evento alocado com esse nome. Digitar novamente? S/N");
			String escolha = sc.next();
			if (escolha.toUpperCase().equals("S")) {
				System.out.println("\nDigite o nome do evento: ");
			} else {
				break;
			}
		}

	}

	private void menuLocalizarEventoID() {
		System.out.println("\nDigite a ID do evento: ");
		String IDEvento = "";
		while (true) {
			IDEvento = sc.next();
			EventoAlocado eventoAlocado = getGrAlocacoes()
					.localizaEventoAlocado(IDEvento);
			if (eventoAlocado != null) {
				System.out.println(eventoAlocado.getSala().getID() + ":"
						+ eventoAlocado.getEvento().getId());
				break;
			}
			System.out
					.println("Nao existe evento alocado com esse ID. Digitar novamente? S/N");
			String escolha = sc.next();
			if (escolha.toUpperCase().equals("S")) {
				System.out.println("\nDigite a ID do evento: ");
			} else {
				break;
			}
		}

		sc.nextLine();

	}

	public void menuDesalocarEvento() throws Exception {

		System.out
				.println("______________________________________________________");
		System.out.println("\n# Desalocar Evento #");
		System.out.println("\nDigite a ID do evento: ");

		String IDEvento = "";
		String escolha = "S";
		while (true) {
			IDEvento = sc.next();
			EventoAlocado evento = getGrAlocacoes().localizaEventoAlocado(
					IDEvento);
			if (evento != null) {
				System.out.println("\nEvento alocado em: "
						+ evento.getSala().getID() + ":"
						+ evento.getEvento().getId());
				break;
			}
			System.out
					.println("Nao existe evento alocado com esse ID. Digitar novamente? S/N");
			escolha = sc.next();
			if (escolha.toUpperCase().equals("S")) {
				System.out.println("\nDigite a ID do evento: ");
			} else {
				break;
			}
		}
		sc.nextLine();

		if (escolha.toUpperCase().equals("S")) {
			System.out
					.println("\nTem certeza que deseja desalocar esse evento? S/N");
			while (true) {
				escolha = sc.next();
				if (escolha.toUpperCase().equals("S")) {
					getGrAlocacoes().desalocaEvento(IDEvento);
					System.out.println("Evento desalocado com sucesso!");
					break;
				} else if (escolha.toUpperCase().equals("N")) {
					break;
				}
				System.out.println("\nOpcao invlida. Digite novamente:");

			}
		}

		System.out
				.println("______________________________________________________");
		System.out.println("\nEscolha o que deseja fazer agora:");
		System.out.println("1 - Desalocar um outro evento");
		System.out.println("2 - Voltar ao menu principal");
		System.out.println("\nDigite o numero escolhido: ");

		while (true) {
			int opcao = sc.nextInt();
			if (opcao == 1) {
				menuDesalocarEvento();
				break;
			} else if (opcao == 2) {
				menuPrincipal();
				break;
			}
			System.out.println("\nNumero invlido. Digite novamente:");
		}

	}

	public void menuCancelarEvento() throws Exception {
		System.out
				.println("______________________________________________________");
		System.out.println("\n# Cancelar Evento #");
		System.out.println("\nDigite a ID do evento: ");

		String IDEvento = "";
		String escolha = "S";
		while (true) {
			IDEvento = sc.next();
			EventoAlocado evento = getGrAlocacoes().localizaEventoAlocado(
					IDEvento);
			Evento evento1 = getGrAlocacoes()
					.localizaEventoAdicionado(IDEvento);
			if (evento != null) {
				System.out.println("\nEvento alocado em: "
						+ evento.getSala().getID() + ":"
						+ evento.getEvento().getId());
				break;
			} else if (evento1 != null) {
				break;
			}
			System.out
					.println("Nao existe evento alocado/adicionado com esse ID. Digitar novamente? S/N");
			escolha = sc.next();
			if (escolha.toUpperCase().equals("S")) {
				System.out.println("\nDigite a ID do evento: ");
			} else {
				break;
			}
		}
		sc.nextLine();

		if (escolha.toUpperCase().equals("S")) {
			System.out
					.println("\nTem certeza que deseja cancelar esse evento? S/N");
			while (true) {
				escolha = sc.next();
				if (escolha.toUpperCase().equals("S")) {
					getGrAlocacoes().cancelarEvento(IDEvento);
					System.out.println("Evento cancelado com sucesso!");
					break;
				} else if (escolha.toUpperCase().equals("N")) {
					break;
				}
				System.out.println("\nOpcao invlida. Digite novamente:");
			}
		}
		System.out
				.println("______________________________________________________");
		System.out.println("\nEscolha o que deseja fazer agora:");
		System.out.println("1 - Cancelar um outro evento");
		System.out.println("2 - Voltar ao menu principal");
		System.out.println("\nDigite o numero escolhido: ");

		while (true) {
			int opcao = sc.nextInt();
			if (opcao == 1) {
				menuCancelarEvento();
				break;
			} else if (opcao == 2) {
				menuPrincipal();
				break;
			}
			System.out.println("\nNumero invalido. Digite novamente:");
		}

	}

	public void menuRemoverSala() throws Exception {
		System.out
				.println("______________________________________________________");
		System.out.println("\n# Remover sala #");
		System.out.println("\nDigite a ID da sala: ");

		String IDSala = "";
		String escolha = "S";
		while (true) {
			IDSala = sc.next();
			Sala evento = getGrAlocacoes().localizaSala(IDSala);
			if (evento != null) {
				break;
			}
			System.out
					.println("Nao existe sala com esse ID. Digitar novamente? S/N");
			escolha = sc.next();
			if (escolha.toUpperCase().equals("S")) {
				System.out.println("\nDigite a ID da sala: ");
			} else {
				break;
			}
		}
		sc.nextLine();

		if (escolha.toUpperCase().equals("S")) {
			System.out
					.println("\nTem certeza que deseja remover essa sala? S/N");
			while (true) {
				escolha = sc.next();
				if (escolha.toUpperCase().equals("S")) {
					getGrAlocacoes().removeSala(IDSala);
					System.out.println("Sala removida com sucesso!");
					break;
				} else if (escolha.toUpperCase().equals("N")) {
					break;
				}
				System.out.println("\nOpcao invalida. Digite novamente:");
			}
		}
		System.out
				.println("______________________________________________________");
		System.out.println("\nEscolha o que deseja fazer agora:");
		System.out.println("1 - Remover outra sala");
		System.out.println("2 - Voltar ao menu principal");
		System.out.println("\nDigite o numero escolhido: ");

		while (true) {
			int opcao = sc.nextInt();
			if (opcao == 1) {
				menuRemoverSala();
				break;
			} else if (opcao == 2) {
				menuPrincipal();
				break;
			}
			System.out.println("\nNumero invalido. Digite novamente:");
		}

	}

	/**
	 * Metodo para acesso e gerencia das alocacoes. De acordo com o refactory.
	 * Dessa forma nao eh preciso acessar diretamente o atributo.
	 * 
	 * @param grAlocacoes
	 */
	public void setGrAlocacoes(FachadaAlocacao grAlocacoes) {
		this.grAlocacoes = grAlocacoes;
	}

	/**
	 * Metodo para acesso e gerencia das alocacoes. De acordo com o refactory.
	 * Dessa forma nao eh preciso acessar diretamente o atributo.
	 * 
	 * @return
	 */
	public FachadaAlocacao getGrAlocacoes() {
		return grAlocacoes;
	}

	public void menuSair() {
		System.exit(0);
	}

	public static void main(String[] args) throws Exception {
		MainMenu menu = new MainMenu();
		menu.menuPrincipal();
	}
}
